package com.msb.c09;

import java.util.concurrent.TimeUnit;

/**
 * @author: xw
 * @create: 2022/10/3 9:40
 * @description:不要以字符串常量作为锁定对象
 *   在下面的例子中，m1和m2其实锁定的是同一个对象
 *   这种情况还会发生比较诡异的现象，比如你用到了一个类库，在该类库中代码锁定了字符串“Hello”，
 *   但是你读不到源码，所以你在自己的代码中也锁定了"Hello",这时候就有可能发生非常诡异的死锁阻塞，
 *   因为你的程序和你用到的类库不经意间使用了同一把锁
 */
public class DoNotLockString {
    String s1 = "hello";
    String s2 = "hello";

    void m1(){
        synchronized (s1){
            System.out.println("s1---"+ Thread.currentThread().getName());
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            m2();
            System.out.println("s1---end"+ Thread.currentThread().getName());
        }
    }

    void m2(){
        synchronized (s2){
            String name = Thread.currentThread().getName();
            System.out.println("s2---" +Thread.currentThread().getName());
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if("t2".equals(name)){
                m1();
            }
            System.out.println("s2---end-" +Thread.currentThread().getName());
        }
    }

    public static void main(String[] args) {
        DoNotLockString t = new DoNotLockString();
        new Thread(t::m1,"t1").start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        new Thread(t::m2,"t2").start();
    }
}
